#pragma once
#include <malloc.h>

namespace umtl
{
	class static_alloc;

	template< typename T >
	class stack_allocator
	{
	public:
		typedef T                 value_type;
		typedef value_type*       pointer;
		typedef const value_type* const_pointer;
		typedef value_type&       reference;
		typedef const value_type& const_reference;
		typedef std::size_t       size_type;
		typedef std::ptrdiff_t    difference_type;

		inline pointer address(reference x) const { return &x; }

		inline const_pointer address(const_reference x) const { 
			return &x;
		}

		inline pointer allocate(size_type n, const_pointer = 0) {
			return (pointer)_malloca( n * sizeof(T) );
		}

		inline void deallocate(pointer p, size_type) {
			_freea(p);
		}

		inline size_type max_size() const { 
			return static_cast<size_type>(-1) / sizeof(value_type);
		}

		inline void construct(pointer p, const value_type& x) { 
			::new(p)value_type(x);
		}
		inline void destroy(pointer p) { p; p->~value_type(); }

		stack_allocator() {}
		stack_allocator(const stack_allocator&) {}
		template <class U> 
		stack_allocator(const stack_allocator<U>&) {}
		~stack_allocator() {}

		template <class U> 
		struct rebind { typedef stack_allocator<U> other; };

	private:
		void operator=(const stack_allocator&);

		boost::coroutines::stack_allocator allocator;
	};

	template<> class stack_allocator<void>
	{
		typedef void        value_type;
		typedef void*       pointer;
		typedef const void* const_pointer;

		template <class U> 
		struct rebind { typedef stack_allocator<U> other; };
	};
}